import TouchDot from "./TouchDot"
import { PieceType, PlayerType } from "./GameDefine"
import BasePiece from "./Pieces/BasePiece"
import Algorithm from "./Algorithm"


const { ccclass, property } = cc._decorator

/** 棋盘上格子宽度 */
const WLINE: number = 9
/** 棋盘上各自高度 */
const HLINE: number = 10

@ccclass
export default class Board extends cc.Component {

    @property({ type: cc.Prefab, displayName: "触摸点预制体" })
    touchDotPrefab: cc.Prefab = null;

    @property({ type: cc.Prefab, displayName: "棋子预制体" })
    piecePrefab: cc.Prefab = null;

    @property({ type: cc.Node, displayName: "蓝色选择框" })
    blueSelecter: cc.Node = null;

    @property({ type: cc.Node, displayName: "红色选择框" })
    redSelecter: cc.Node = null;

    /** 我的玩家类型 */
    playerType: PlayerType = PlayerType.RED;
    /** 触摸点数组 */
    touchDotArray: TouchDot[][] = [];
    /** 当前已选择 touchdot */
    selectedDot: TouchDot = null;
    /** 移动目标 touchdot */
    moveTargetDot: TouchDot = null;
    /** 当前点击的 touchdot */
    clickDot: TouchDot = null;
    /** 移动算法 */
    algorithm: Algorithm = null;

    onLoad() {
        this.initTouchDot()
        this.initPiece()

        // 先让选择框隐藏
        this.blueSelecter.active = false
        this.redSelecter.active = false
        // 加载棋子走法校验的类
        this.algorithm = new Algorithm()
        this.algorithm.playerType = this.playerType
        this.algorithm.boarddots = this.touchDotArray
    }

    start() {

    }

    /** 初始化棋盘触摸点 */
    private initTouchDot() {
        let blockWidth: number = (this.node.width / (WLINE - 1))
        let blockHeight: number = (this.node.height / (HLINE - 1))

        for (let i = 0; i < HLINE; ++i) {
            this.touchDotArray[i] = []
            for (let j = 0; j < WLINE; ++j) {
                let node: cc.Node = cc.instantiate(this.touchDotPrefab)
                node.setPosition(new cc.Vec2(blockWidth * j, blockHeight * i))
                let touchDot: TouchDot = node.getComponent(TouchDot)
                touchDot.index.x = i
                touchDot.index.y = j
                touchDot.board = this
                this.touchDotArray[i].push(touchDot)
                this.node.addChild(node)
            }
        }
    }

    //初始化棋子
    private initPiece() {
        //初始化我方棋子
        this.createPiece(PieceType.ROOKS, this.playerType, cc.v2(0, 0))
        this.createPiece(PieceType.KNIGHTS, this.playerType, cc.v2(0, 1))
        this.createPiece(PieceType.ELEPHANT, this.playerType, cc.v2(0, 2))
        this.createPiece(PieceType.MANDARIN, this.playerType, cc.v2(0, 3))
        this.createPiece(PieceType.KING, this.playerType, cc.v2(0, 4))
        this.createPiece(PieceType.MANDARIN, this.playerType, cc.v2(0, 5))
        this.createPiece(PieceType.ELEPHANT, this.playerType, cc.v2(0, 6))
        this.createPiece(PieceType.KNIGHTS, this.playerType, cc.v2(0, 7))
        this.createPiece(PieceType.ROOKS, this.playerType, cc.v2(0, 8))
        this.createPiece(PieceType.CANNONS, this.playerType, cc.v2(2, 1))
        this.createPiece(PieceType.CANNONS, this.playerType, cc.v2(2, 7))
        this.createPiece(PieceType.PAWNS, this.playerType, cc.v2(3, 0))
        this.createPiece(PieceType.PAWNS, this.playerType, cc.v2(3, 2))
        this.createPiece(PieceType.PAWNS, this.playerType, cc.v2(3, 4))
        this.createPiece(PieceType.PAWNS, this.playerType, cc.v2(3, 6))
        this.createPiece(PieceType.PAWNS, this.playerType, cc.v2(3, 8))

        //初始化对方棋子
        let optType: PlayerType = this.playerType == PlayerType.RED ? PlayerType.BLACK : PlayerType.RED
        this.createPiece(PieceType.ROOKS, optType, cc.v2(9, 0))
        this.createPiece(PieceType.KNIGHTS, optType, cc.v2(9, 1))
        this.createPiece(PieceType.ELEPHANT, optType, cc.v2(9, 2))
        this.createPiece(PieceType.MANDARIN, optType, cc.v2(9, 3))
        this.createPiece(PieceType.KING, optType, cc.v2(9, 4))
        this.createPiece(PieceType.MANDARIN, optType, cc.v2(9, 5))
        this.createPiece(PieceType.ELEPHANT, optType, cc.v2(9, 6))
        this.createPiece(PieceType.KNIGHTS, optType, cc.v2(9, 7))
        this.createPiece(PieceType.ROOKS, optType, cc.v2(9, 8))
        this.createPiece(PieceType.CANNONS, optType, cc.v2(7, 1))
        this.createPiece(PieceType.CANNONS, optType, cc.v2(7, 7))
        this.createPiece(PieceType.PAWNS, optType, cc.v2(6, 0))
        this.createPiece(PieceType.PAWNS, optType, cc.v2(6, 2))
        this.createPiece(PieceType.PAWNS, optType, cc.v2(6, 4))
        this.createPiece(PieceType.PAWNS, optType, cc.v2(6, 6))
        this.createPiece(PieceType.PAWNS, optType, cc.v2(6, 8))
    }

    /**
     * 触发点告诉我它被点击了
     * @param touchDot 被点击的点
     * @returns 
     */
    onDotTouchEnd(touchDot: TouchDot) {
        let opDot = this.selectedDot
        let tgDot = touchDot
        // 如果两次点击的点是同一个，就不理它
        if (opDot === tgDot) { return }

        if (tgDot.piece) {
            //点击到了棋子
            if (!opDot || !opDot.piece || opDot.piece.playerType === tgDot.piece.playerType) {
                //操作对象不存在或者操作对象没有棋子或者操作的是自己的棋子
                this.blueSelecter.setPosition(tgDot.pos)
                this.blueSelecter.active = true
                this.selectedDot = tgDot
                return
            }
        }
        else if (!opDot || !opDot.piece) {
            return
        }

        this.pieceMove(opDot, tgDot)
    }

    /**
     * 创建棋子
     * @param pieceType 
     * @param playerType 
     * @param index 
     */
    private createPiece(pieceType: PieceType, playerType: PlayerType, index: cc.Vec2) {
        let self = this
        let resName = `./Pieces/${playerType}${pieceType}`
        cc.resources.load(resName, cc.SpriteFrame, (err, asset) => {
            if (!err) {
                let node: cc.Node = cc.instantiate(this.piecePrefab)
                node.getComponent(cc.Sprite).spriteFrame = <cc.SpriteFrame>asset
                self.node.addChild(node)
                node.setContentSize(cc.size(60, 60))
                let touchDot: TouchDot = this.touchDotArray[index.x][index.y]
                let basePiece: BasePiece = node.getComponent(BasePiece)
                basePiece.initPos = touchDot.pos
                if (self.playerType != playerType) {
                    //如果不是己方需要旋转180度
                    node.angle = -180
                }
                basePiece.pieceType = pieceType
                basePiece.playerType = playerType
                basePiece.init()
                touchDot.piece = basePiece
            }
        })
    }

    //棋子移动
    private pieceMove(opDot: TouchDot, tgDot: TouchDot) {
        if (!opDot || !tgDot) {
            return
        }

        if (!this.algorithm.checkPieceMove(opDot, tgDot)) {
            return
        }

        this.redSelecter.setPosition(tgDot.pos)
        this.redSelecter.active = true

        if (opDot.piece) {
            let moveNode = opDot.piece.node
            let oldZIndex = moveNode.zIndex
            let t: cc.Tween<cc.Node> = cc.tween(opDot.piece.node)
                .call(() => {
                    //移动前将节点置顶
                    moveNode.zIndex = 999
                })
                .to(0.2, { position: tgDot.pos })

            if (tgDot.piece) {
                let oldNode = tgDot.piece.node
                //将棋子移动到新位置
                t = t.call(() => {
                    //销毁原来的棋子
                    oldNode.destroy()
                })
            }

            t.call(() => {
                //将节点zindex还原
                moveNode.zIndex = oldZIndex
            }).start()

            tgDot.piece = opDot.piece
            opDot.piece = null
        }
    }
}
